classdef DetailHelper< handle
    %UNTITLED12 此处显示有关此类的摘要
    %   此处显示详细说明

    properties (Constant)
        ww = 2;
        wh = 2;

        trueW = 240 - Helper.ww;
        trueH = 150 - Helper.wh;
        whRatio = Helper.trueW / Helper.trueH;

        args = {};
    end
    methods(Static = true)
        %% 三阈值绘图并保存
        function showThreeThresh(ccc, BW, strTitle, bSave, fileSaveCCC)
            thresh = multithresh(ccc(BW), 2);%%三阈值 OK
            seg_c = imquantize(ccc, thresh);
            RGBc = DetailHelper.SetRGBwithBackBlack(seg_c, BW);
            
            figure,imshow(RGBc),title(strTitle)

            if bSave == true
                DetailHelper.SaveFigure2Img(fileSaveCCC)
            end
        end
        %% 二阈值绘图并保存
        function showTwoThresh(ccc, BW, strTitle, bSave, fileSaveCCC)
            threshC = DetailHelper.GetThresh(ccc(BW));%%
            BWc = ccc < threshC;

            BBB = DetailHelper.SetRGBwithBackBlack(BWc & BW, BW);
 
            figure,imshow(BBB), title(strTitle)            

            if bSave == true
                DetailHelper.SaveFigure2Img(fileSaveCCC)
            end
        end
        %% 获得不同阈值 2022-08-03
        function [threshC3, threshR3, threshC2, threshR2, threshNoR] = GetMultiThresh(aaa, bbb, BW)
            threshC3 = multithresh(aaa(BW), 2);%%三阈值 2022-05-24 添加ccc
            threshR3 = multithresh(bbb(BW), 2);%%三阈值 2022-05-24 添加rrr
            threshC2 = multithresh(aaa(BW), 1);%%二阈值 2022-05-25 添加
            threshR2 = multithresh(bbb(BW), 1);%%二阈值 2022-05-25 添加            
             
             BWr1 = bbb < threshR2;% 根2                
             BWsb = ~BWr1 & BW;
% % %        直接计算   全局threshNoR还是没用     
             threshNoR = multithresh(aaa(BWsb), 1);%%是否可以全局计算，这里是局部计算            
        end
        
        
        %% 显示/保存直方图
        function showHistgram(ccc, BW, strTitle, bSave, fileSaveCCC)            
            figure, histogram(ccc(BW)), title(strTitle)       
            if bSave == true
                DetailHelper.SaveFigure2Img(fileSaveCCC)
            end
        end
        
        % %   聚类分析,用途不大
        function kmeanColors(img8)
            img88 = double(img8)/255;
            red = img88(:, :, 1);
            gre = img88(:, :, 2);
            blu = img88(:, :, 3);
            red(~BW) = nan;
            gre(~BW) = nan;
            blu(~BW) = nan;
            
            red2 = red(:);
            gre2 = gre(:);
            blu2 = blu(:);
            
            imgN = cat(2, red2, gre2, blu2);
            [idx, C] = kmeans(imgN, 3);
            figure,title('聚类结果');
            idx2 = reshape(idx, size(red, 1), size(red, 2));
            idx2(~BW) = 4;
            
            RGB = label2rgb(idx2);
            imshow(RGB)
        end
        
        %% 矩阵保存图片
        function saveImage(ccc, bSave, fileSaveCCC)
            if bSave
                imwrite(ccc, fileSaveCCC)
            end
        end
        
        %% 
        function AreaFilter(BWseed, BW)
           stats = regionprops('table', BWseed, 'Area', 'MajorAxisLength', 'MinorAxisLength', 'PixelIdxList');        
           
           area = stats.Area;
           [mm, in] = max(area);
           
           pLists = stats.PixelIdxList{in};
           maxRad = stats.MajorAxisLength(in);
           minRad = stats.MinorAxisLength(in);
           rad = (maxRad+minRad) /2;            
        end
        

       % % % % % % % 助手方法
        function rgb = SetRGBwithBackBlack(data, BW)
            rgb = label2rgb(data);
            rgb = imoverlay(rgb, ~BW, 'black');%%替换掉下面代码
            return;
            
            rred = rgb(:, :, 1);
            ggre = rgb(:, :, 2);
            bblu = rgb(:, :, 3);
            rred(~BW) = 0;
            ggre(~BW) = 0;
            bblu(~BW) = 0;
            rgb = cat(3, rred, ggre, bblu);
        end
        function rgb = setBWColor(rgb, BW, color)
            rgb = imoverlay(rgb, BW, color/255);%%最新实现
            return;            
            rred = rgb(:, :, 1);
            ggre = rgb(:, :, 2);
            bblu = rgb(:, :, 3);
            rred(BW) = color(1);
            ggre(BW) = color(2);
            bblu(BW) = color(3);
            rgb = cat(3, rred, ggre, bblu);
        end
        
        function rgb = setImgWithColor(rgb, rows, cols, color)
            rred = rgb(:, :, 1) ;
            ggre = rgb(:, :, 2);
            bblu = rgb(:, :, 3);
            
            ind = sub2ind(size(rred),rows,cols);
            rred(ind) = color(1);
            ggre(ind) = color(2);
            bblu(ind) = color(3);
            rgb = cat(3, rred, ggre, bblu);
        end        

        
        %% 创建一个圆形Mask     
        function mask = CreateCirclesMask(szImg, centers, radii)
            xc = centers(:, 1);
            yc = centers(:, 2);
            xDim = szImg(1);
            yDim = szImg(2);
            [xx, yy] = meshgrid(1:yDim, 1:xDim);
            mask = false(xDim, yDim);
            for ii = 1:numel(radii)
                mask = mask | hypot(xx - xc(ii), yy - yc(ii)) <= radii(ii);
            end
        end
        
        
        function BW3 = DoMorph(BW, w)
            type = 'disk';
            type = 'square';
            se = strel(type, w);

            BW2 = imclose(BW, se);
            BW3 = imopen(BW2, se);
        end  
        function BW3 = DoMorph2(BW, w1, w2)
            type = 'disk';
            type = 'square';
            se1 = strel(type, w1);
            se2 = strel(type, w2);

            BW2 = imclose(BW, se1);
            BW3 = imopen(BW2, se2);
        end
        
        function [thresh, level] = GetThresh(I)%%返回阈值，256等分
            edges = NewUtil.GetEdges(I, 256);
            counts = histcounts(I, edges);
            level = otsuthresh(counts);
            thresh = edges(1) + (edges(end) - edges(1)) * level;%%
        end
        

        
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %         
        
        function [dist4, BWskel] = GetDistForAPath(BWbud, D2, D3)
            
            BWskel = bwskel(BWbud);
            [dd1, ins1] = min(D2(BWskel));%%接口点测地距
            [dd2, ins2] = min(D3(BWskel));%%牙尖测地距
            [rows, cols] = find(BWskel);
            pt1 = [cols(ins1), rows(ins1)];
            pt2 = [cols(ins2), rows(ins2)];

            BWskel2 = imdilate(BWskel, strel('square', 3));
            DD = bwdistgeodesic(BWskel2, pt1(1), pt1(2), 'quasi-euclidean');%%
            dist4 = DD(pt2(2), pt2(1)) + dd1 + dd2;     
        end
        
        %%根据种子的x-y坐标，进行编号。
        function [pos, xx, yy, bSort] = findIndexForSeed(stats)
            centroid = stats.Centroid;
            majLength = stats.MajorAxisLength;
            medLength = median(majLength);
            
            bSort = false;
            
            xx = centroid(:, 1);
            yy = centroid(:, 2);
            
            pos = 1 : length(xx);
            for i = 1 : length(pos) -1                
                for j = i+1 : length(pos)
                    if yy(j) < yy(i) - 1.5 * medLength
                        tmp = xx(i);
                        xx(i) = xx(j);
                        xx(j) = tmp;
                        
                        tmp = yy(i);
                        yy(i) = yy(j);
                        yy(j) = tmp;
                        
                        tmp = pos(i);
                        pos(i) = pos(j);
                        pos(j) = tmp;
                        
                        bSort = true;
                    elseif xx(i) > xx(j) && abs(yy(j) - yy(i)) <= 1.5 * medLength
                        tmp = xx(i);
                        xx(i) = xx(j);
                        xx(j) = tmp;
                        
                        tmp = yy(i);
                        yy(i) = yy(j);
                        yy(j) = tmp;
                        
                        tmp = pos(i);
                        pos(i) = pos(j);
                        pos(j) = tmp;
                        
                        bSort = true;
                    end
                end                
            end            
        end
        % % % % % % % % % %
        function SetWindowTitle()
           set(gcf,'Name', get(gca,'Title').String,'NumberTitle','off') 
        end
            
        
        function f = GetAFrame()%%截图时，增加坐标轴
            ax = gca;
            ax.Units = 'pixels';
            pos = ax.Position;
            margx = 45;
            margy = 30;
            rect = [-margx, -margy, pos(3)+2*margx,pos(4)+2*margy];
            f = getframe(gca,rect);
        end
        
        %%最新画图
        function SaveFigure2Img(imgname)
            %% 获取figure界面
            frame = getframe(gcf);
            %% 转为图像
            im = frame2im(frame);
            %% 保存
            imwrite(im,imgname);
        end

    end
    
end